/**
 * 
 */
package com.ac4j.algorithm;

import java.util.ArrayList;

import com.ac4j.match.Match;
import com.ac4j.match.Position;
import com.ac4j.sample.Sample;
import com.ac4j.sample.SampleImage;

/**
 * @author Administrator
 * 
 */
public class GreedyStrategy extends AbstractStrategy {
	float threshold = 0.95f;

	/**
	 * @param locatingalgorithm
	 * @param recognitionalgorithm
	 * @param sourceimage
	 * @param prototypesamples
	 * @param threshold
	 */
	public GreedyStrategy(AbstractLocatingAlgorithm locatingalgorithm,
			AbstractRecognitionAlgorithm recognitionalgorithm,
			SampleImage sourceimage, ArrayList<Sample> prototypesamples,
			float threshold) {
		super(locatingalgorithm, recognitionalgorithm, sourceimage,
				prototypesamples);
		this.threshold = threshold;
	}

	public GreedyStrategy(AbstractLocatingAlgorithm locatingalgorithm,
			AbstractRecognitionAlgorithm recognitionalgorithm,
			SampleImage sourceimage, ArrayList<Sample> prototypesamples) {
		super(locatingalgorithm, recognitionalgorithm, sourceimage,
				prototypesamples);
		// TODO Auto-generated constructor stub
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ac4j.algorithm.AbstractStrategy#Execute()
	 */
	@Override
	public ArrayList<Match> Execute() {
		Position p = null;
		ArrayList<Match> matchlist = new ArrayList<Match>();
		float tempscore = 0;
		float positionscore = 0;
		// int matchwidth;
		int i = 0;

		while (locatingalgorithm.HasNext()) {
			p = locatingalgorithm.NextPosition();
			i = 0;
			positionscore = 0;
			for (Sample s : prototypesamples) {
				try {
					tempscore = recognitionalgorithm
							.GetMatchScoreForSpecificSample(sourceimage, p, s);
					if (tempscore >= threshold) {
						// matchwidth = s.getSampleImage().getWidth();
						matchlist.add(new Match(s, p, tempscore));
						positionscore = ((positionscore * i++) + tempscore)
								/ (float) i;
						break;
					}
				} catch (IndexOutOfBoundsException ie) {
					// Release the OutOfBounds Exception

				} catch (Exception e) {
					// Unknown Exception, quit it
					break;
				}
			}
			locatingalgorithm.Feedback(positionscore);
		}

		return matchlist;
	}

	/**
	 * @return the threshold
	 */
	public float getThreshold() {
		return threshold;
	}

	/**
	 * @param threshold
	 *            the threshold to set
	 */
	public void setThreshold(float threshold) {
		if (threshold >= 0 && threshold <= 1)
			this.threshold = threshold;
	}

}
